<?php

declare(strict_types=1);

/**
 * Author: Jesse
 * Email : jessedev@163.com
 * Date: 2024/7/3 10:42
 * FileName: RpcExceptionHandler.php
 * DESC: The Relentless Pursuit of Perfection.
 */

namespace Common\Kernel\Rpc;

use Common\Kernel\Exception\BusinessException;
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\ExceptionHandler\ExceptionHandler;
use Hyperf\ExceptionHandler\Formatter\FormatterInterface;
use Swow\Psr7\Message\ResponsePlusInterface;
use Throwable;

/**
 * RPC 服务端异常处理器
 */
class RpcExceptionHandler extends ExceptionHandler
{
    /**
     * 注入
     *
     * @param StdoutLoggerInterface $logger
     * @param FormatterInterface $formatter
     */
    public function __construct(protected StdoutLoggerInterface $logger, protected FormatterInterface $formatter)
    {
    }

    /**
     * @param Throwable $throwable
     * @param ResponsePlusInterface $response
     * @return ResponsePlusInterface
     */
    public function handle(Throwable $throwable, ResponsePlusInterface $response): ResponsePlusInterface
    {
        # 控制台日志
        console_log()->debug($this->formatter->format($throwable));
        console_log()->debug(sprintf('%s[%s] in %s', $throwable->getMessage(), $throwable->getLine(), $throwable->getFile()));

        # 文件日志
        logger()->warning('Rpc Exception Handler', ['exception' => $this->formatter->format($throwable)]);

        $this->stopPropagation();

        return $response;
    }

    /**
     * @param Throwable $throwable
     * @return bool
     */
    public function isValid(Throwable $throwable): bool
    {
        // 业务异常不记录日志
        return !$throwable instanceof BusinessException;
    }
}